/*	
 *  Copyright (c) 2009-@year@. The GUITAR group at the University of Maryland. Names of owners of this group may
 *  be obtained by sending an e-mail to atif@cs.umd.edu
 * 
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
 *  documentation files (the "Software"), to deal in the Software without restriction, including without 
 *  limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 *	the Software, and to permit persons to whom the Software is furnished to do so, subject to the following 
 *	conditions:
 * 
 *	The above copyright notice and this permission notice shall be included in all copies or substantial 
 *	portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
 *	LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 
 *	EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
 *	IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 
 *	THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
 */
package edu.umd.cs.imut.executor;

import java.io.File;
import java.util.List;
import java.util.Map;

import edu.umd.cs.imut.event.IEvent;
import edu.umd.cs.imut.executor.IExecutorMonitor;
import edu.umd.cs.imut.model.IComponent;
import edu.umd.cs.imut.model.IIDGenerator;
import edu.umd.cs.imut.model.IO;
import edu.umd.cs.imut.model.WebDefaultIDGenerator;
import edu.umd.cs.imut.model.data.AttributesType;
import edu.umd.cs.imut.model.data.ComponentMapType;
import edu.umd.cs.imut.model.data.ComponentType;
import edu.umd.cs.imut.model.data.EventMapType;
import edu.umd.cs.imut.model.data.EventType;
import edu.umd.cs.imut.model.data.GUIMap;
import edu.umd.cs.imut.model.data.ObjectFactory;
import edu.umd.cs.imut.model.data.PropertyType;

/**
 * 
 * Update object looking up map during test case execution
 * 
 * @author <a href="mailto:baonn@cs.umd.edu"> Bao N. Nguyen </a>
 * 
 */
public class WebMapUpdater extends IExecutorMonitor {

	String mapFile;
	GUIMap map;

	ObjectFactory factory = new ObjectFactory();
	IIDGenerator idGenerator = WebDefaultIDGenerator.getInstance();

	/**
	 * @param mapFile
	 */
	public WebMapUpdater(String mapFile) {
		super();
		this.mapFile = mapFile;

		File file = new File(mapFile);
		// // Init map
		if (file.exists()) {
			map = (GUIMap) IO.readObjFromFile(mapFile, GUIMap.class);
		} else {
			map = factory.createGUIMap();
		}

		map = factory.createGUIMap();
		if (map.getEventMap() == null) {
			map.setEventMap(factory.createEventMapType());
		}

		if (map.getComponentMap() == null) {
			map.setComponentMap(factory.createComponentMapType());
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.cs.umd.imut.executor.IExecutorMonitor#afterAllEvents()
	 */
	@Override
	void afterAllEvents() {
		IO.writeObjToFile(map, mapFile);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.cs.umd.imut.executor.IExecutorMonitor#afterEvent()
	 */
	@Override
	void afterEvent() {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.cs.umd.imut.executor.IExecutorMonitor#beforeAllEvents()
	 */
	@Override
	void beforeAllEvents() {
		List<IComponent> lComponent = executor.getAllComponents();
		ComponentMapType componentMap = map.getComponentMap();
		EventMapType eventMap = map.getEventMap();

		for (IComponent iComponent : lComponent) {

			if (!iComponent.hasEvent())
				continue;

			List<IEvent> eventList = iComponent.getEventList();

			// Add component
			ComponentType dataComponent = getComponentState(iComponent);
			String ID = idGenerator.generateID(iComponent);
			String componentID = ID;

			dataComponent.setComponentID(componentID);
			componentMap.getComponent().add(dataComponent);

			// Add events
			int eventIDCounter = 0;
			for (IEvent event : eventList) {
				EventType dataEvent = factory.createEventType();

				// Class name
				String eventClass = event.getClass().getName();
				dataEvent.setAction(eventClass);

				// ID
				String eventID = "e" + ID;
				if (eventIDCounter > 0)
					eventID += "_" + eventIDCounter;
				eventIDCounter++;

				dataEvent.setEventID(eventID);
				dataEvent.setComponentID(componentID);

				eventMap.getEvent().add(dataEvent);

			}
		}

	}

	/**
	 * @param iComponent
	 * @return
	 */
	private ComponentType getComponentState(IComponent iComponent) {
		Map<String, List<String>> properties = iComponent.getProperties();

		ComponentType component = factory.createComponentType();
		AttributesType attributes = factory.createAttributesType();
		component.setAttributes(attributes);

		for (String propertyName : properties.keySet()) {
			PropertyType propertyType = factory.createPropertyType();
			propertyType.setName(propertyName);
			List<String> values = properties.get(propertyName);
			propertyType.getValue().addAll(values);
			attributes.getProperty().add(propertyType);
		}

		return component;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.cs.umd.imut.executor.IExecutorMonitor#beforeEvent()
	 */
	@Override
	void beforeEvent() {
		// TODO Auto-generated method stub

	}

}
